package com.twotiger.and.view;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;

import com.twotiger.and.activity.account.repayplan.RepayPlanCalendarPage;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.Typeface;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import android.widget.Scroller;
import android.widget.Toast;

/**
 * 日历控件 功能：获得点选的日期区间
 * 
 */
public class CalendarView3 extends View {
    private final static String TAG = "anCalendar";
    private Calendar calendar;
    private Surface surface;
    private List<String> repayMentDateList;
    private List<Integer> specialDay = new ArrayList<Integer>();
    private String mDownDay; //按下的日期

    //给控件设置监听事件
    private OnItemClickListener onItemClickListener;

    public CalendarView3(Context context) {
        super(context);
        init();
        mScroller = new Scroller(context);
    }

    public CalendarView3(Context context, AttributeSet attrs) {
        super(context, attrs);
        init();
        mScroller = new Scroller(context);
    }

    private void init() {
        surface = new Surface();
        surface.density = getResources().getDisplayMetrics().density;
        setBackgroundColor(surface.bgColor);

        Calendar calendar = Calendar.getInstance();
        currentYear = calendar.get(Calendar.YEAR);
        currentMonth = calendar.get(Calendar.MONTH) + 1;
        nowYear = currentYear;
        nowMonth = currentMonth;
        nowDay = calendar.get(Calendar.DAY_OF_MONTH);
        calendarObj = new CalendarObj(index111, currentYear, currentMonth);
        computeDate();

    }

    private void computeDate() {
        nextYear = lastYear = currentYear;

        nextMonth = currentMonth + 1;
        lastMonth = currentMonth - 1;

        if (currentMonth == 12) {
            nextYear++;
            nextMonth = 1;
        }
        if (currentMonth == 1) {
            lastYear--;
            lastMonth = 12;
        }
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        Log.d(TAG, "measure");
        wwidth = surface.width = getResources().getDisplayMetrics().widthPixels;
        criticalWidth = (int) (1F / 5F * wwidth); //屏幕宽度�?5分之1

        surface.height = (int) (getResources().getDisplayMetrics().heightPixels * 1.8 / 5);

        widthMeasureSpec = View.MeasureSpec
            .makeMeasureSpec(surface.width, View.MeasureSpec.EXACTLY);
        heightMeasureSpec = View.MeasureSpec.makeMeasureSpec(surface.height,
            View.MeasureSpec.EXACTLY);
        setMeasuredDimension(widthMeasureSpec, heightMeasureSpec);
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
    }

    @Override
    protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
        Log.d(TAG, "[onLayout] changed:" + (changed ? "new size" : "not change") + " left:" + left
                   + " top:" + top + " right:" + right + " bottom:" + bottom);
        if (changed) {
            surface.init();
        }
        super.onLayout(changed, left, top, right, bottom);
    }

    @Override
    protected void onDraw(Canvas canvas) {
        Log.d(TAG, "onDraw");

        drawCalendar(canvas, (index111 - 1) * wwidth, lastYear, lastMonth);
        drawCalendar(canvas, index111 * wwidth, currentYear, currentMonth);
        drawCalendar(canvas, (index111 + 1) * wwidth, nextYear, nextMonth);

        drawWeek(canvas, (index111 - 1) * wwidth);
        drawWeek(canvas, index111 * wwidth);
        drawWeek(canvas, (index111 + 1) * wwidth);

    }

    private int getXByIndex(int i) {
        return i % 7 + 1; // 1 2 3 4 5 6 7
    }

    private int getYByIndex(int i) {
        return i / 7 + 1; // 1 2 3 4 5 6
    }

    /**
     * 
     * @param canvas
     * @param index
     * @param text
     */
    private void drawCellText(Canvas canvas, int index, String text, int color, float textSize) {
        int x = getXByIndex(index);
        int y = getYByIndex(index);
        surface.datePaint.setColor(color);
        surface.datePaint.setTextSize(textSize);
        float cellY = (float) (surface.monthHeight + surface.weekHeight + (y - 1) * surface.cellHeight
                      + surface.cellHeight * 3 / 4f - (surface.density * 2.5 + 0.5f));
        float cellX = (surface.cellWidth * (x - 1))
                      + (surface.cellWidth - surface.datePaint.measureText(text)) / 2f;
        canvas.drawText(text, cellX, cellY, surface.datePaint);
    }

    /**
     * 给日历设需要画圆框的日期
     * 
     * @param dateList
     */
    public void setSelectedDate(List<String> dateList) {
        repayMentDateList = null;
        repayMentDateList = dateList;
        if (repayMentDateList != null) {
            for (int i = 0; i < repayMentDateList.size(); i++) {
                String date = repayMentDateList.get(i);
                specialDay.add(Integer.parseInt(date.substring(date.length() - 2, date.length())));
            }
        }
        invalidate();
    }

    /**
     * 给日历设按下的日期（按下日期需要画实心圆背景）
     * 
     * @param downDay
     */
    public void setDownDate(String downDay) {
        mDownDay = downDay;
        //        if(downDay != null){
        //            downDayIndex = Integer.parseInt(mDownDay);
        //        }
        invalidate();
    }

    private void drawCalendar(Canvas canvas, int offset, int year, int month) {
        canvas.save(); //锁画布，将之前的画布状态保存
        canvas.translate(offset, 0);//把当前画布的原点移到(offsetX, 0),后面的操作都以(offsetX, 0)作为参照点，默认原点为(0,0)  

        int current = (int) (offset / wwidth);
        int[] gregorianCurrent = calendarObj.getGregorianCreated().get(current);

        if (null == gregorianCurrent) {
            gregorianCurrent = calendarObj.buildGregorian(year, month);
        }

        int downDayIndex = -1;
        if (mDownDay != null) {
            downDayIndex = Integer.parseInt(mDownDay);
        }

        boolean drawToday;
        for (int i = 0; i < gregorianCurrent.length; i++) {
            drawToday = false;
            String str = gregorianCurrent[i] + "";
            if ("0".equals(str)) {
                str = "";
            }
            int color = surface.textColor;
            if (year < nowYear) {
                color = surface.borderColor;
            } else if (year == nowYear) {
                if (month < nowMonth) {
                    color = surface.borderColor;
                } else if (month == nowMonth) {
                    if (gregorianCurrent[i] < nowDay) {
                        color = surface.borderColor;
                    } else if (gregorianCurrent[i] == nowDay) {
                        drawToday = true;
                        color = surface.todayNumberColor;
                    }
                }
            }
            if (specialDay.size() > 0 && specialDay.contains(gregorianCurrent[i])) {
                drawCellEmptyBg(canvas, i, surface.todayNumberColor); //画圆框
                color = surface.todayNumberColor;
            }

            if (downDayIndex != -1 && gregorianCurrent[i] == downDayIndex) {
                drawCellBg(canvas, i, surface.todayNumberColor); //画实心圆背景
                color = surface.bgColor;
            }
            drawCellText(canvas, i, drawToday ? "今天" : str, color,
                drawToday ? surface.cellHeight * 0.39f : surface.cellHeight * 0.5f); //画文字
        }
        calendarObj.getGregorianCreated().put(current, gregorianCurrent);

        canvas.restore(); //把当前画布返回（调整）到上一个save()状态之前  
    }

    /**
     * 
     * @param canvas
     * @param index
     * @param color
     */
    private void drawCellBg(Canvas canvas, int index, int color) {
        int x = getXByIndex(index);
        int y = getYByIndex(index);
        surface.cellBgPaint.setColor(color);
        float left = surface.cellWidth * (x - 1) + surface.borderWidth;
        float top = surface.monthHeight + surface.weekHeight + (y - 1) * surface.cellHeight
                    + surface.borderWidth;
        //        canvas.drawRect(left, top, left + surface.cellWidth - surface.borderWidth,
        //            top + surface.cellHeight - surface.borderWidth, surface.cellBgPaint);
        canvas.drawCircle(left + (surface.cellWidth - surface.borderWidth) / 2,
            top + (surface.cellHeight - surface.borderWidth) / 2,
            (surface.cellHeight - surface.borderWidth) / 2, surface.cellBgPaint);
    }

    /**
     * 获取日历日期
     */
    public Date getCurrentDate() {
        return calendarObj.getDownDate(index111, -1);
    }

    /**
     * 
     * @param canvas
     * @param index
     * @param color
     */
    private void drawCellEmptyBg(Canvas canvas, int index, int color) {
        int x = getXByIndex(index);
        int y = getYByIndex(index);
        surface.cellBgEmptyPaint.setColor(color);
        float left = surface.cellWidth * (x - 1) + surface.borderWidth;
        float top = surface.monthHeight + surface.weekHeight + (y - 1) * surface.cellHeight
                    + surface.borderWidth;

        canvas.drawCircle(left + (surface.cellWidth - surface.borderWidth) / 2,
            top + (surface.cellHeight - surface.borderWidth) / 2,
            (surface.cellHeight - surface.borderWidth * 4) / 2, surface.cellBgEmptyPaint);
    }

    /**
     * 获取按下的位置的坐标   +++++
     * 
     * @param index
     * @return
     */
    public Float[] getPositionOfSelected(String downDate) {
        Float[] positionSelected = new Float[3];
        int index = 0;
        if (downDate != null) {
            index = Integer.parseInt(downDate) + calendarObj.getStartIndex(index111) - 1;
        }
        int x = getXByIndex(index);
        int y = getYByIndex(index);
        float left = surface.cellWidth * (x - 1) + surface.borderWidth;
        float top = surface.monthHeight + surface.weekHeight + (y - 1) * surface.cellHeight
                    + surface.borderWidth;
        float size = (surface.cellHeight - surface.borderWidth) / 2;

        positionSelected[0] = left + 10.0f; //降低误差
        positionSelected[1] = top;
        positionSelected[2] = size;
        return positionSelected;
    }

    private void drawWeek(Canvas canvas, int offset) {
        canvas.save(); //锁画布，将之前的画布状�?�保�?
        canvas.translate(offset, 0);//把当前画布的原点移到(offsetX, 0),后面的操作都�?(offsetX, 0)作为参照点，默认原点�?(0,0)  
        float weekTextY = surface.monthHeight + surface.weekHeight * 3 / 4f;
        for (int i = 0; i < surface.weekText.length; i++) {
            float weekTextX = i
                              * surface.cellWidth
                              + (surface.cellWidth - surface.weekPaint
                                  .measureText(surface.weekText[i])) / 2f;
            canvas.drawText(surface.weekText[i], weekTextX, weekTextY, surface.weekPaint);
        }
        canvas.restore();
    }

    //给控件设置监听事件
    public void setOnItemClickListener(OnItemClickListener onItemClickListener) {
        this.onItemClickListener = onItemClickListener;
    }

    //监听接口
    public interface OnItemClickListener {
        void OnItemClick(Date downDate, MotionEvent event);

        void OnFilingToRight();

        void OnFilingToLeft();
    }

    @Override
    public void computeScroll() {
        if (mScroller.computeScrollOffset()) {
            scrollTo(mScroller.getCurrX(), mScroller.getCurrY());
            //            invalidate();
        } else {
            //            requestLayout();
        }
    }

    public void smoothScrollTo(int fx, int fy) {
        int dx = fx - mScroller.getFinalX();
        int dy = fy - mScroller.getFinalY();
        smoothScrollBy(dx, dy);
    }

    private void smoothScrollBy(int dx, int dy) {
        mScroller.startScroll(mScroller.getFinalX(), mScroller.getFinalY(), dx, dy, 800);
        invalidate();
    }

    @Override
    public boolean dispatchTouchEvent(MotionEvent event) { //这个界面上的动作均由自己来处理，不让父类拦截
        getParent().requestDisallowInterceptTouchEvent(true);
        return super.dispatchTouchEvent(event);
    }

    //  上一月
    public void clickLeftMonth() {
        if (RepayPlanCalendarPage.reqLock == 0) {
            index111--;
            currentMonth = (currentMonth - 1) % 12;
            if (currentMonth == 0) {
                currentMonth = 12;
                currentYear--;
            }
            computeDate();
            smoothScrollTo(wwidth * index111, 0);
            lastMoveX = wwidth * index111;

            mDownDay = null;
            specialDay.clear();
            invalidate();
        }
    }

    //下一月    并计算日期情况
    public void clickRightMonth() {

        if(RepayPlanCalendarPage.reqLock == 0){
            index111++;
            currentMonth = (currentMonth + 1) % 13;
            if (currentMonth == 0) {
                currentMonth = 1;
                currentYear++;
            }
            computeDate();
            lastMoveX = wwidth * index111;
            smoothScrollTo(wwidth * index111, 0);
            
            mDownDay = null;
            specialDay.clear();
            invalidate();
        }
    }

    private int lastPointX;
    private int lastMoveX;
    private int wwidth;
    private int index111;
    private int criticalWidth;
    private Scroller mScroller;
    private CalendarObj calendarObj;
    private int lastYear, currentYear, nextYear; //会变化
    private int lastMonth, currentMonth, nextMonth; //会变化
    private int nowYear, nowMonth, nowDay; //真正的今天的年月日，不会变化

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        if(RepayPlanCalendarPage.reqLock != 0){
            return true;
        }
        switch (event.getAction()) {
        case MotionEvent.ACTION_DOWN:
            lastPointX = (int) event.getX();
            break;
        case MotionEvent.ACTION_MOVE:
            int totalMoveX = (int) (lastPointX - event.getX()) + lastMoveX;
            smoothScrollTo(totalMoveX, 0);
            break;
        case MotionEvent.ACTION_UP:
            if (Math.abs(lastPointX - event.getX()) > 10) {
                if (lastPointX > event.getX()) {//向左滑动
                    if (Math.abs(lastPointX - event.getX()) >= criticalWidth) {
                        clickRightMonth();
                        onItemClickListener.OnFilingToLeft();
                    } else {
                        smoothScrollTo(wwidth * index111, 0);
                    }

                } else if (lastPointX < event.getX()) { //向右�?
                    if (Math.abs(lastPointX - event.getX()) >= criticalWidth) {
                        clickLeftMonth();
                        onItemClickListener.OnFilingToRight();
                    } else {
                        smoothScrollTo(wwidth * index111, 0);
                    }

                }
            } else {
                setSelectedDateByCoor(event.getX(), event.getY(), event);
            }
            break;
        }
        return true;
    }

    private void setSelectedDateByCoor(float x, float y, MotionEvent event) {
        if (y > surface.monthHeight + surface.weekHeight) {
            int m = (int) (Math.floor(x / surface.cellWidth) + 1);
            int n = (int) (Math.floor((y - (surface.monthHeight + surface.weekHeight))
                                      / Float.valueOf(surface.cellHeight)) + 1);
            int downIndex = (n - 1) * 7 + m - 1;
            Log.d(TAG, "downIndex:" + downIndex);

            if (calendarObj.isShowMonth(index111, downIndex)) {
                Date downDate = calendarObj.getDownDate(index111, downIndex);
                onItemClickListener.OnItemClick(downDate, event);
            }
            //            calendar.setTime(curDate);
            //            if (isLastMonth(downIndex)) {
            //                calendar.add(Calendar.MONTH, -1);
            //                return;
            //            } else if (isNextMonth(downIndex)) {
            //                calendar.add(Calendar.MONTH, 1);
            //                return;
            //            }
            //            calendar.set(Calendar.DAY_OF_MONTH, date[downIndex]);
            //            downDate = calendar.getTime();
        }
        invalidate();
    }

    public class Surface {
        public float density;
        public int width; // 整个控件的宽度
        public int height; // 整个控件的高度
        public float monthHeight; // 显示月的高度
        //public float monthChangeWidth; // 上一月、下一月按钮宽度
        public float weekHeight; // 显示星期的高度
        public float cellWidth; // 日期方框宽度
        public float cellHeight; // 日期方框高度  
        public float borderWidth;
        public int bgColor = Color.parseColor("#FFFFFF");
        public int textColor = Color.BLACK;
        //private int textColorUnimportant = Color.parseColor("#666666");
        public int btnColor = Color.parseColor("#666666");
        public int borderColor = Color.parseColor("#CCCCCC");
        public int transparentColor = Color.parseColor("#ffffff");
        public int todayNumberColor = Color.parseColor("#fe953c");
        public int cellDownColor = Color.parseColor("#CCFFFF");
        public int cellSelectedColor = Color.parseColor("#99CCFF");
        public Paint borderPaint;
        public Paint monthPaint;
        public Paint weekPaint;
        public Paint datePaint;
        public Paint monthChangeBtnPaint;
        public Paint cellBgPaint;
        public Paint cellBgEmptyPaint;

        public Path boxPath; // 边框路径
        //public Path preMonthBtnPath; // 上一月按钮三角形
        //public Path nextMonthBtnPath; // 下一月按钮三角形
        public String[] weekText = { "一", "二", "三", "四", "五", "六", "日" };

        //public String[] monthText = {"Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"};

        public void init() {
            float temp = height / 7f;
            monthHeight = 0;//(float) ((temp + temp * 0.3f) * 0.6);
            //monthChangeWidth = monthHeight * 1.5f;
            weekHeight = (float) ((temp + temp * 0.3f) * 0.7);
            cellHeight = (height - monthHeight - weekHeight) / 6f;
            cellWidth = width / 7f;
            borderPaint = new Paint();
            borderPaint.setColor(borderColor);
            borderPaint.setStyle(Paint.Style.STROKE);
            borderWidth = (float) (0.5 * density);
            // Log.d(TAG, "borderwidth:" + borderWidth);
            borderWidth = borderWidth < 1 ? 1 : borderWidth;
            borderPaint.setStrokeWidth(borderWidth);
            monthPaint = new Paint();
            monthPaint.setColor(textColor);
            monthPaint.setAntiAlias(true);
            float textSize = cellHeight * 0.4f;
            monthPaint.setTextSize(textSize);
            monthPaint.setTypeface(Typeface.DEFAULT_BOLD);
            weekPaint = new Paint();
            weekPaint.setColor(borderColor);
            weekPaint.setAntiAlias(true);
            float weekTextSize = weekHeight * 0.6f;
            weekPaint.setTextSize(weekTextSize);
            weekPaint.setTypeface(Typeface.DEFAULT);
            datePaint = new Paint();
            datePaint.setColor(textColor);
            datePaint.setAntiAlias(true);
            float cellTextSize = cellHeight * 0.5f;
            datePaint.setTextSize(cellTextSize);
            datePaint.setTypeface(Typeface.DEFAULT);
            boxPath = new Path();
            //boxPath.addRect(0, 0, width, height, Direction.CW);
            //boxPath.moveTo(0, monthHeight);
            boxPath.rLineTo(width, 0);
            boxPath.moveTo(0, monthHeight + weekHeight);
            boxPath.rLineTo(width, 0);
            for (int i = 1; i < 6; i++) {
                boxPath.moveTo(0, monthHeight + weekHeight + i * cellHeight);
                boxPath.rLineTo(width, 0);
                boxPath.moveTo(i * cellWidth, monthHeight);
                boxPath.rLineTo(0, height - monthHeight);
            }
            boxPath.moveTo(6 * cellWidth, monthHeight);
            boxPath.rLineTo(0, height - monthHeight);
            //preMonthBtnPath = new Path();
            //int btnHeight = (int) (monthHeight * 0.6f);
            //preMonthBtnPath.moveTo(monthChangeWidth / 2f, monthHeight / 2f);
            //preMonthBtnPath.rLineTo(btnHeight / 2f, -btnHeight / 2f);
            //preMonthBtnPath.rLineTo(0, btnHeight);
            //preMonthBtnPath.close();
            //nextMonthBtnPath = new Path();
            //nextMonthBtnPath.moveTo(width - monthChangeWidth / 2f,
            //      monthHeight / 2f);
            //nextMonthBtnPath.rLineTo(-btnHeight / 2f, -btnHeight / 2f);
            //nextMonthBtnPath.rLineTo(0, btnHeight);
            //nextMonthBtnPath.close();
            monthChangeBtnPaint = new Paint();
            monthChangeBtnPaint.setAntiAlias(true);
            monthChangeBtnPaint.setStyle(Paint.Style.FILL_AND_STROKE);
            monthChangeBtnPaint.setColor(btnColor);
            cellBgPaint = new Paint();
            cellBgPaint.setAntiAlias(true);
            cellBgPaint.setStyle(Paint.Style.FILL);
            cellBgPaint.setColor(cellSelectedColor);

            cellBgEmptyPaint = new Paint();
            cellBgEmptyPaint.setAntiAlias(true);
            cellBgEmptyPaint.setStyle(Paint.Style.STROKE);
            cellBgEmptyPaint.setStrokeWidth(3);
            cellBgEmptyPaint.setColor(cellSelectedColor);
        }
    }
}
